Difference of development between custom component and full-fledged component for ESPHome
There are two approaches that can be used to develop a custom component for ESPHome: 1. A simplified version described in the ESPHome documentation (Custom Sensor Compoent and Generic Custom Component) 2. Native - "full-fledged" component that you can find e.g. ESPHome Build-in Components and its creation is described in the Contribution Guide
For better communication to distinguish components, I will call the former Simple and the latter Native.
The main difference between the two is that Native implementation provides better reusability, as you can use external_components
feature to point to the local or remote (github) location in your .yaml
device configuration to simply use some additional components except the build-in into ESPHome. Additionally Native component has more advantages over the component configuration validation thanks to Python and configuration schemes.
The Simple component development is quite well described in the ESPHome documentation. In a nutshell, it just requires creating the .h
+ optionally .cpp
file with the C++ (Arduino) component implementation and then the yaml
file that registers the component so it can be used as any other ESPHome component. All that is clearly explained in the above documentation references.
In the case of the Native component development, this gets more tricky. The contribution guide sheds a bit of light on how to start but without many details. The most tricky part is how to properly write the __init__
and/orsensor.py
which defines the component, validation, and C++ code generation (more details in the contribution guide). Most of the time it requires checking other component's implementations and based on that conclude what is actually needed. It's not that hard but requires a bit of Python knowledge. The C++ part is not that much different than the Simple component implementation. If you already have Simple implementation it can be copy/pasted, add namespace esphome
, another inner for the component, and you are good to go.
If you would like to understand better the difference between the Simple and Native component implementation take a look at my repository. I implemented the same sensor using both approaches. You can find the Simple component implementation in custom_components/mq9 and Native in components/mq. Also, the example of how to use it is defined in mq9_test.yaml
The Native component is loaded thanks to the external_components
definition in config_base.yaml.
To switch between the Native and Simple component usage uncomment the line that defines mq9_base
in the mq9_test.yaml.